import {createStore, Store, useStore as baseUseStore} from 'vuex'
import {ethers} from "ethers";
import {message} from "ant-design-vue";
import {InjectionKey} from 'vue'
import t from '@/utils/i18n'

export interface State {
    provider: any,
    account: string | '',
    spinning: boolean | true,
    net: number | 0,
    gasPrice: number | 5000000000,
    slippage: any | 0.1,
    deadline: number | 20,
    multiPath: number | 0,
}
// defind injection key
export const key: InjectionKey<Store<State>> = Symbol()

export const store = createStore<State>({
    state() {
        return {
            provider: {},
            signer: {},
            account: '',
            spinning: true,
            net: 0,
            gasPrice: 5000000000,
            slippage: 0.1,
            deadline: 20,
            multiPath: 0,
            transactions: {},
            block: 0,
        }
    },
    mutations: {
        setProvider: (state: State, provider: any) => {
            state.provider = provider;
        },
        setAccount(state: State, account: string) {
            state.account = account;
        },
        setSpinning(state: State, spinning: boolean) {
            state.spinning = spinning;
        }
    },
    actions: {
        async connect({commit, dispatch}) {
            // @ts-ignore
            let provider = window.ethereum;
            if (typeof provider !== 'undefined') {
                try {
                    // add bsc netWork
                    if(process.env.NODE_ENV !== 'development'){
                        await provider.request({
                            method: 'wallet_addEthereumChain',
                            params: [
                                {
                                    "chainId": "0x38",
                                    "chainName": "Binance Smart Chain Mainnet",
                                    "nativeCurrency": {
                                        "name": "BNB",
                                        "symbol": "bnb",
                                        "decimals": 18
                                    },
                                    "rpcUrls": [
                                        "https://bsc-dataseed.binance.org/"
                                    ],
                                    "blockExplorerUrls": [
                                        "https://bscscan.com/"
                                    ]
                                }
                            ],
                        });
                    }
                    await provider.request({method: 'eth_requestAccounts'});
                } catch (err: any) {
                    if (err.code === 4001) {
                        message.error(t('walletConnect.error'));
                    } else {
                        console.error(err);
                    }
                    return
                }
            }
            let web3:any = new ethers.providers.Web3Provider(provider);
            commit("setProvider", web3)
            // Get Current Connect Account
            let address = await web3.listAccounts()

            provider.on('accountsChanged', function (accounts: Array<string>) {
                let len = accounts[0]?.length
                if (len > 0) {
                    message.info(t('walletConnect.switchAccounts'))
                    commit('setAccount', accounts[0])
                    window.location.reload();
                } else {
                    localStorage.setItem("account", 'false')
                    window.location.reload();
                }
            });
            //setAccount to Vuex
            commit('setAccount', address[0])
            if (provider.isConnected) {
                message.success(t('walletConnect.success'))
                localStorage.setItem("account", 'true')
            } else {
                message.error(t('walletConnect.disconnect'))
                localStorage.setItem("account", 'false')
            }
            provider.on('chainChanged', (chainId: string) => {
                window.location.reload();
            });
        }
    }
})

export function useStore(): Store<any> {
    return baseUseStore(key);
}